<?php
/**
 * Created by PhpStorm.
 * User: meng
 * Date: 2022/10/1
 * Time: 14:01
 */

namespace lib\utils;

class TreeDataUtils
{
    /**
     * 扁平数据
     * @var array
     */
    private $data;

    /**
     * 父级ID
     * @var string|null
     */
    public $parentField = 'parent_id';

    /**
     * 主键
     * @var string|null
     */
    public $primaryField = 'id';

    /**
     * 树形数据中子集键名
     * @var string|null
     */
    public $childrenField = 'children';

    /**
     * 叶子节点子集默认数据
     * @var array|null
     */
    public $defaultChildrenValue;

    public function __construct ($data, $parentField = null, $primaryField = null, $childrenField = null, $defaultChildrenValue = []) {
        $this->data = $data;
        if (!empty($parentField)) {
            $this->parentField = $parentField;
        }
        if (!empty($primaryField)) {
            $this->primaryField = $primaryField;
        }
        if (!empty($childrenField)) {
            $this->childrenField = $childrenField;
        }
        $this->defaultChildrenValue = is_null($defaultChildrenValue) ? null : [];
    }

    /**
     * 获取子元素
     * @param $myid
     * @return array|bool
     */
    private function getChild ($myid) {
        $temp = [];
        foreach ($this->data as $k => $v) {
            if ($v[$this->parentField] == $myid) {
                $temp[] = $v;
            }
        }
        return $temp ?? false;
    }

    /**
     * 获取树形数据
     * @param int? $pid
     * @return array|null
     */
    public function getTree ($pid = 0): ?array {
        $tmp = [];
        $child = $this->getChild($pid);
        if (is_array($child)) {
            foreach ($child as $v) {
                $v[$this->childrenField] = $this->getTree($v[$this->primaryField]);
                array_push($tmp, $v);
            }
        }
        return empty($tmp) ? $this->defaultChildrenValue : $tmp;
    }

    /**
     * 获取数据中所有叶子节点
     * @return array
     */
    public function getLeaf (): array {
        $temp = [];
        foreach ($this->data as $v) {
            if (empty($this->getChild($v[$this->primaryField]))) {
                array_push($temp, $v);
            }
        }
        return $temp;
    }
}
